package Recommender.Covisited;

import DataModel.ArrDataModel;
import DataModel.DataModel;
import IO.ReadFile;
import java.io.FileWriter;
import java.io.IOException;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author tuyetphuong
 */
public class MaTrixCovisited {

    public int iNumOfItem;
    public int[][] iMaTrixCoVisited;
    public MaTrixCovisited matrix;

    public void Init_Covisited(ArrDataModel arr)
    {
        arr.GetNumOFItem();
        arr.GetNumOFUser();
        CountCovisted(arr);
    }
    public MaTrixCovisited() {
    }

    public MaTrixCovisited(int _iNumOfItem, int[][] _iMatrixCoVisited) {
        iNumOfItem = _iNumOfItem;
        System.out.print(iNumOfItem);
        System.out.print("\n");
        iMaTrixCoVisited = new int[iNumOfItem + 1][iNumOfItem + 1];
        for (int i = 1; i <= iNumOfItem; i++) {
            for (int j = 1; j <= iNumOfItem; j++) {
                iMaTrixCoVisited[i][j] = _iMatrixCoVisited[i][j];
            }

        }
    }

    public void Init(int _numofitem) {
        iNumOfItem = _numofitem;
        iMaTrixCoVisited = new int[iNumOfItem + 1][iNumOfItem + 1];
        for (int i = 1; i <= iNumOfItem; i++) {
            for (int j = 1; j <= iNumOfItem; j++) {
                iMaTrixCoVisited[i][j] = 0;
            }
        }
    }

    public float DistanceTimeStamp(DataModel datamodel1, DataModel datamodel2) {
        float distance = (float) (1.0 * datamodel1.iTimeStamp - 1.0 * datamodel2.iTimeStamp);

        distance = Math.abs(distance);
       // System.out.print(distance);
       // System.out.print("  ");
        distance = (float) (1.0 * distance / 60);
        distance = (float) (1.0 * distance / 60);
        distance = (float) (1.0 * distance / 24);
      //System.out.print(distance);
     //System.out.print("\n");
        return distance;
    }

    public int IsCoVisited(DataModel datamodel1, DataModel datamodel2) {
        if ((datamodel1.GetIDUser() == datamodel2.GetIDUser()) && (datamodel1.iRating==1 && datamodel2.iRating==1)
                && (DistanceTimeStamp(datamodel1, datamodel2) <=3)) {
           // System.out.print(DistanceTimeStamp(datamodel1, datamodel2));
            //System.out.print("\n");
            return 1;
        }
        return 0;
    }

    public void CountCovisted(ArrDataModel arr) {
    //    MaTrixCovisited matrix1;
        iMaTrixCoVisited = new int[8500+1][8500+1];
        for (int i = 1; i <= arr._MaxItem; i++) {
            for (int j = 1; j <= arr._MaxItem; j++) {
                iMaTrixCoVisited[i][j] = 0;
            }
        }
        int Count[] = arr.CountIDUser();
        int a = arr.numofrow;
        for (int i = 0; i < a - 1; i++) {
            for (int j = i + 1; j < i + Count[arr.arrmodel.get(i).GetIDUser()] && j < a; j++) {
                if (IsCoVisited(arr.arrmodel.get(i), arr.arrmodel.get(j)) == 1
                       ) {
                    iMaTrixCoVisited[arr.arrmodel.get(i).GetIDItem()][arr.arrmodel.get(j).GetIDItem()]++;
                    iMaTrixCoVisited[arr.arrmodel.get(j).GetIDItem()][arr.arrmodel.get(j).GetIDItem()]++;
                }
            }

        }


        matrix = new MaTrixCovisited(arr._MaxItem, iMaTrixCoVisited);
        
    }

    /*  public float[] GetPoint(int iuser, ArrDataModel arr) {
    int a = arr._MaxItem;
    float[] iPoint = new float[a + 1];
    for (int i = 1; i <= a; i++) {
    iPoint[i] = (float) 0.0;
    }
    int[] iFindITemSetLastUse = arr.FindItemLastUse(iuser);
    int b = iFindITemSetLastUse.length;
    for (int i = 1; i <= a; i++) {
    iPoint[i] = 0;
    for (int j = 0; j < b; j++) {
    iPoint[i] +=Score(iFindITemSetLastUse[j], i,  arr);
    }

    }
    return iPoint;
    }*/
    public float Score(int i, int j, ArrDataModel arr) {
        float score = 0;
        int s1 = iMaTrixCoVisited[i][j];
        int s2 = 0;
        for (int m = i - 50; m > 0 && m <= i + 50 && m < arr._MaxItem; m++) {
            s2 += iMaTrixCoVisited[i][m];

        }
        if (s2 == 0) {
            return (float) 0.0;
        }
        score = (float) ((float) s1 / (float) s2);
        return score;
    }
    public void Update(int u, int s, int time, ArrDataModel arr) {
        DataModel model = new DataModel(u, s, 1, time);
        for (int i = 0; i < arr.numofrow; i++) {

            if (IsCoVisited(model, arr.arrmodel.get(i)) == 1) {
                iMaTrixCoVisited[s][arr.arrmodel.get(i).GetIDItem()]++;
                iMaTrixCoVisited[arr.arrmodel.get(i).GetIDItem()][s]++;
            }

        }
    }






    public float GetPoint_Covisited(int iuser, int item, ArrDataModel arr) {
        int a = arr._NumOfItem;
        float iPoint = 0;
        int[] iFindITemSetLastUse = arr.FindItemLastUse(iuser);
        int b = iFindITemSetLastUse.length;
        for (int j = 0; j < b; j++) {
            iPoint += Score(iFindITemSetLastUse[j], item, arr);
        }
        return (float) (0.1 + iPoint);
    }

    public int GetPoint_Covisited_Standar(int user, int item, ArrDataModel arr) {
        float p = GetPoint_Covisited(user, item, arr);
        int point;
        System.out.print(p);
        System.out.print("\n");
        if (p >0.00) {
            point = 1;
        } else {
            point = 0;
        }
        return point;
    }

    public static void main(String[] args) throws IOException {
         float f;
        int sotuvandung = 0;
        int sotuvan = 0;
        int sodanhgia = 0;
        int sodanhgiadung = 0;
        int taptest = 0;
        float recall = 0;
        float precsion = 0;
        float mae = 0;
        float rmse = 0;
        int solantuvanrecall = 0;
        int solantuvanprecsion = 0;
        ArrDataModel arr = new ArrDataModel();
        ReadFile readfile = new ReadFile();
        arr = readfile.ReadTrainFile("u6.base");
        arr.GetNumOFItem();
        arr.GetNumOFUser();
        ArrDataModel arr1 = new ArrDataModel();
        ReadFile readfile1 = new ReadFile();
        arr1 = readfile.TestFile5();
        arr1.GetNumOFItem();
        arr1.GetNumOFUser();
        MaTrixCovisited matrix1 = new MaTrixCovisited();
        //matrix1.CountCovisted(arr);
        matrix1.Init_Covisited(arr);
        for( int i =1; i<=1000;i++)
        {
            System.out.print(matrix1.GetPoint_Covisited(100, i, arr));
            System.out.print("\n");
        }
     
    }
}
